package com.sunday.boot3.user.center.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sunday.boot3.user.center.pojo.dto.permissions.PermissionsConstants;
import com.sunday.boot3.user.center.pojo.dto.user.*;
import com.sunday.boot3.user.center.repository.dao.UserDao;
import com.sunday.boot3.user.center.repository.dao.UserRoleDao;
import com.sunday.boot3.user.center.repository.entity.Permissions;
import com.sunday.boot3.user.center.repository.entity.User;
import com.sunday.boot3.user.center.service.UserService;
import com.sunday.common.core.asserts.BusinessAssert;
import com.sunday.common.core.converter.MapperConvert;
import com.sunday.common.core.enums.ErrorCodeEnum;
import com.sunday.common.core.permissions.PermissionsEncode;
import com.sunday.common.core.remoting.base.page.PageResultDTO;
import com.sunday.common.leaf.core.IdWorker;
import com.sunday.common.mybatis.plus.query.PageWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description: 用户表 服务实现类
 * @author: zsy
 * @Create: 2024/09/22 16:24:38
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserDao userDao;

    private final UserRoleDao userRoleDao;

    /**
     * 获取登陆用户信息
     *
     * @param
     * @return {@link GetLoginUserResDTO}
     */
    @Override
    public GetLoginUserResDTO getLoginUser() {
        LambdaQueryWrapper<User> userQW = Wrappers.lambdaQuery();
        userQW.eq(User::getId, 1591298380020060173L);
        User user = userDao.getOne(userQW);
        BusinessAssert.notNull(user, ErrorCodeEnum.A0_201);
        List<Permissions> permissionsList = userRoleDao.findPermissionsByUserId(user.getId());
        Map<Integer, Set<String>> permissionCategoryMap = permissionsList.stream().collect(Collectors.groupingBy(Permissions::getCategory, Collectors.mapping(Permissions::getUrl, Collectors.toSet())));
        GetLoginUserResDTO getLoginUserResDTO = new GetLoginUserResDTO();
        getLoginUserResDTO.setId(user.getId());
        getLoginUserResDTO.setUsername(user.getUsername());
        getLoginUserResDTO.setRoutePermissions(
                Optional.ofNullable(permissionCategoryMap.get(PermissionsConstants.PermissionCategoryEnum.ROUTE_PERMISSIONS.getCode()))
                        .map(p -> p.toArray(new String[0]))
                        .orElseGet(() -> new String[0])
        );
        getLoginUserResDTO.setFineGritPermissions(
                Optional.ofNullable(permissionCategoryMap.get(PermissionsConstants.PermissionCategoryEnum.FINE_GRIT_PERMISSIONS.getCode()))
                        .map(p -> p.toArray(new String[0]))
                        .orElseGet(() -> new String[0])
        );
        return getLoginUserResDTO;
    }

    /**
     * 获取授权用户信息
     *
     * @param getAuthUserReqDTO
     * @return {@link GetAuthUserResDTO}
     */
    @Override
    public GetAuthUserResDTO getAuthUser(GetAuthUserReqDTO getAuthUserReqDTO) {
        LambdaQueryWrapper<User> permissionQW = Wrappers.lambdaQuery();
        permissionQW.eq(User::getUsername, getAuthUserReqDTO.getUsername());
        User user = userDao.getOne(permissionQW);
        BusinessAssert.notNull(user, ErrorCodeEnum.A0_201);
        GetAuthUserResDTO getAuthUserResDTO = MapperConvert.map(user, GetAuthUserResDTO.class);
        long[] sum = PermissionsEncode.generate(userRoleDao.findPermissionsByUserId(user.getId()), Permissions::getPosition, Permissions::getCode);
        getAuthUserResDTO.setPermissionsSum(sum);
        return getAuthUserResDTO;
    }

    /**
     * @Description: 新增 用户表 数据
     * @Param: [saveUserReqDTO]
     * @Return: void
     * @Author: zsy
     * @Time: 2024/09/22 16:24:38
     */
    @Override
    public void save(SaveUserReqDTO saveUserReqDTO) {
        User user = MapperConvert.map(saveUserReqDTO, User.class);
        user.setId(IdWorker.getId());
        user.setCreateDate(LocalDate.now());
        user.setCreateTime(LocalDateTime.now());
        BusinessAssert.isTrue(userDao.save(user), ErrorCodeEnum.A0_440);
    }

    /**
     * @Description: 删除 用户表 数据
     * @Param: [removeUserReqDTO]
     * @Return: void
     * @Author: zsy
     * @Time: 2024/09/22 16:24:38
     */
    @Override
    public void remove(RemoveUserReqDTO removeUserReqDTO) {
        BusinessAssert.isTrue(userDao.removeByIds(removeUserReqDTO.getIds()), ErrorCodeEnum.A0_440);
    }

    /**
     * @Description: 修改 用户表 数据
     * @Param: [updateUserReqDTO]
     * @Return: void
     * @Author: zsy
     * @Time: 2024/09/22 16:24:38
     */
    @Override
    public void update(UpdateUserReqDTO updateUserReqDTO) {
        LambdaUpdateWrapper<User> userUW = Wrappers.lambdaUpdate();
        userUW.eq(User::getId, updateUserReqDTO.getId());
        userUW.set(User::getUsername, updateUserReqDTO.getUsername())
                .set(User::getPassword, updateUserReqDTO.getPassword());
        BusinessAssert.isTrue(userDao.update(userUW), ErrorCodeEnum.A0_440);
    }

    /**
     * @Description: 获取 用户表 分页列表数据
     * @Param: [pageUserReqDTO]
     * @Return: com.sunday.common.core.remoting.base.page.PageResultDTO<com.sunday.boot3.user.center.pojo.dto.user.PageUserResDTO>
     * @Author: zsy
     * @Time: 2024/09/22 16:24:38
     */
    @Override
    public PageResultDTO<PageUserResDTO> page(PageUserReqDTO pageUserReqDTO) {
        LambdaQueryWrapper<User> userQW = Wrappers.lambdaQuery();
        userQW.eq(ObjectUtils.isNotEmpty(pageUserReqDTO.getId()), User::getId, pageUserReqDTO.getId())
                .eq(StringUtils.isNotBlank(pageUserReqDTO.getUsername()), User::getUsername, pageUserReqDTO.getUsername())
                .eq(StringUtils.isNotBlank(pageUserReqDTO.getPassword()), User::getPassword, pageUserReqDTO.getPassword())
                .eq(ObjectUtils.isNotEmpty(pageUserReqDTO.getCreateDate()), User::getCreateDate, pageUserReqDTO.getCreateDate())
                .eq(ObjectUtils.isNotEmpty(pageUserReqDTO.getCreateTime()), User::getCreateTime, pageUserReqDTO.getCreateTime());
        return PageWrapper.result(userDao.page(PageWrapper.map(pageUserReqDTO, User::getId), userQW), data -> MapperConvert.map(data, PageUserResDTO.class));
    }

}
